package com.example.wisdomclassroomapi.facade.security;

import com.example.wisdomclassroomapi.common.util.JwtUtil;
import com.example.wisdomclassroomapi.domain.entity.AuthUserEntity;
import com.example.wisdomclassroomapi.domain.repository.AuthUserRepository;
import com.example.wisdomclassroomapi.domain.service.CaptchaDomainService;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.Set;

@Component
public class FormAuthenticationProvider implements AuthenticationProvider {
    @Resource
    private CaptchaDomainService captchaDomainService;
    @Resource
    private AuthUserRepository userRepository;
    @Resource
    private PasswordEncoder passwordEncoder;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        RequestAuthenticationDetails details = (RequestAuthenticationDetails) authentication.getDetails();

        // 校验验证码
        captchaDomainService.checkCaptcha(details.getCaptchaId(), details.getCaptcha());

        // 登录，获取用户信息
        AuthUserEntity entity = userRepository.findByUsername(details.getUsername());
        if (Objects.isNull(entity)) throw new UsernameNotFoundException("用户名不存在");

        //校验密码
        passwordEncoder.matches(details.getPassword(), entity.getPassword());

        // 获取用户权限编码
        Set<SimpleGrantedAuthority> codes = userRepository.getAuthCodeByUserId(entity.getId());

        // 生成结果
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(entity.getId(), entity.getPassword(), codes);
        authenticationToken.setDetails(new ResponseAuthenticationDetails(entity.getId(), entity, JwtUtil.sign(entity.getId()), codes));
        return authenticationToken;
    }

    /**
     * authentication 强转时 支持的类
     * @param authentication Class<?>
     * @return boolean
     */
    @Override
    public boolean supports(Class<?> authentication) {
        return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

}
